package icu.cqcai.xinsi.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.http.client.SimpleClientHttpRequestFactory;


import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 扣子API服务 - 处理与扣子智能体的交互
 */
@Service
public class CozeApiService {

    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;
    private final OssService ossService;
    
    // 扣子API配置
    private static final String BOT_ID = "7515261380430266408";
    private static final String ACCESS_TOKEN = "pat_SwmNZRUPekSdjR31xF4jXMlc6tAV4k50Hiy6dZIsJLVmgK7VUk2gfsKWRTEbDO49";
    private static final String API_URL = "https://api.coze.cn/v3/chat";


    public CozeApiService(OssService ossService) {
        this.restTemplate = new RestTemplate();
        this.objectMapper = new ObjectMapper();
        this.ossService = ossService;
        
        // 配置超时
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(15000); // 连接超时15秒
        factory.setReadTimeout(120000);   // 读取超时2分钟
        this.restTemplate.setRequestFactory(factory);
    }

    /**
     * 上传文件到阿里云OSS
     * @param file 要上传的文件
     * @return 文件URL
     */
    public String uploadFileToOSS(MultipartFile file) {
        return ossService.uploadFile(file);
    }



    /**
     * 发送带文件的消息到扣子智能体
     * @param userMessage 用户消息
     * @param fileUrl 文件URL（通过uploadFile方法获得）
     * @param cozeUserId 扣子用户ID
     * @param conversationId 会话ID
     * @return 智能体回复
     */
    public String sendMessageWithFile(String userMessage, String fileUrl, String cozeUserId, String conversationId) {
        try {
            System.out.println("开始发送带文件的消息到扣子API");
            System.out.println("用户消息: " + userMessage);
            System.out.println("文件URL: " + fileUrl);
            System.out.println("用户ID: " + cozeUserId);
            
            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("bot_id", BOT_ID);
            requestBody.put("user_id", cozeUserId);
            requestBody.put("stream", false);
            
            // 如果有会话ID，添加到请求中
            if (conversationId != null && !conversationId.isEmpty()) {
                requestBody.put("conversation_id", conversationId);
            }
            
            // 构建消息（包含文件引用）
            Map<String, Object> message = new HashMap<>();
            message.put("role", "user");
            message.put("content_type", "text");
            
            // 如果有文件，在消息中提供文件URL
            if (fileUrl != null && !fileUrl.isEmpty()) {
                String contentWithFile = userMessage + "\n\n请访问以下链接查看文件内容：" + fileUrl;
                message.put("content", contentWithFile);
            } else {
                message.put("content", userMessage);
            }
            
            List<Map<String, Object>> messages = new ArrayList<>();
            messages.add(message);
            requestBody.put("additional_messages", messages);

            System.out.println("请求体: " + requestBody);

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + ACCESS_TOKEN);

            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

            // 发送请求
            long startTime = System.currentTimeMillis();
            ResponseEntity<String> response = restTemplate.postForEntity(API_URL, request, String.class);
            long endTime = System.currentTimeMillis();
            
            System.out.println("API调用耗时: " + (endTime - startTime) + "ms");
            System.out.println("响应状态码: " + response.getStatusCode());
            
            if (response.getStatusCode() == HttpStatus.OK) {
                String responseBody = response.getBody();
                System.out.println("响应内容: " + responseBody);
                return parseNonStreamResponse(responseBody);
            } else {
                System.err.println("API调用失败，状态码: " + response.getStatusCode());
                return "抱歉，简历分析服务暂时无法使用，请稍后再试。";
            }
            
        } catch (Exception e) {
            System.err.println("调用扣子API失败: " + e.getMessage());
            e.printStackTrace();
            return "抱歉，简历分析过程中出现错误，请稍后再试。";
        }
    }


    /**
     * 发送消息到扣子智能体（支持上下文）
     * @param userMessage 用户消息
     * @param cozeUserId 扣子用户ID，用于会话隔离和上下文维持
     * @param conversationId 会话ID，用于上下文引用
     * @return 智能体回复
     */
    public String sendMessage(String userMessage, String cozeUserId, String conversationId) {
        try {
            System.out.println("开始调用扣子API - 用户消息: " + userMessage);
            System.out.println("用户ID: " + cozeUserId + ", 会话ID: " + conversationId);
            
            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("bot_id", BOT_ID);
            requestBody.put("user_id", cozeUserId);
            requestBody.put("stream", false); // 改为非流式，便于解析
            
            // 如果有会话ID，添加到请求中以维持上下文
            if (conversationId != null && !conversationId.isEmpty()) {
                requestBody.put("conversation_id", conversationId);
            }
            
            // 构建消息
            Map<String, Object> message = new HashMap<>();
            message.put("role", "user");
            message.put("content", userMessage);
            message.put("content_type", "text");
            
            List<Map<String, Object>> messages = new ArrayList<>();
            messages.add(message);
            requestBody.put("additional_messages", messages);

            System.out.println("请求体: " + requestBody);

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + ACCESS_TOKEN);

            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

            // 发送请求
            long startTime = System.currentTimeMillis();
            ResponseEntity<String> response = restTemplate.postForEntity(API_URL, request, String.class);
            long endTime = System.currentTimeMillis();
            
            System.out.println("API调用耗时: " + (endTime - startTime) + "ms");
            System.out.println("响应状态码: " + response.getStatusCode());
            
            if (response.getStatusCode() == HttpStatus.OK) {
                String responseBody = response.getBody();
                System.out.println("响应内容: " + responseBody);
                return parseNonStreamResponse(responseBody);
            } else {
                System.err.println("API调用失败，状态码: " + response.getStatusCode());
                return "抱歉，智能助手暂时无法回复，请稍后再试。";
            }
            
        } catch (Exception e) {
            System.err.println("调用扣子API失败: " + e.getMessage());
            e.printStackTrace();
            
            // 根据异常类型返回不同的错误消息
            if (e.getMessage().contains("timeout")) {
                return "智能助手响应超时，请稍后重试。";
            } else if (e.getMessage().contains("Connection refused")) {
                return "无法连接到智能助手服务，请检查网络连接。";
            } else {
                return "抱歉，智能助手暂时无法回复，请稍后再试。";
            }
        }
    }

    /**
     * 发送消息到扣子智能体（带历史消息上下文）
     * @param userMessage 用户消息
     * @param cozeUserId 扣子用户ID
     * @param conversationId 会话ID
     * @param historyMessages 历史消息列表
     * @return 智能体回复
     */
    public String sendMessageWithHistory(String userMessage, String cozeUserId, String conversationId, List<Map<String, Object>> historyMessages) {
        try {
            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("bot_id", BOT_ID);
            requestBody.put("user_id", cozeUserId);
            requestBody.put("stream", false);
            
            // 如果有会话ID，添加到请求中
            if (conversationId != null && !conversationId.isEmpty()) {
                requestBody.put("conversation_id", conversationId);
            }
            
            // 构建消息列表（包含历史消息和当前消息）
            List<Map<String, Object>> allMessages = new ArrayList<>();
            
            // 添加历史消息（最近的几条，避免请求过大）
            if (historyMessages != null && !historyMessages.isEmpty()) {
                // 只取最近的10条消息作为上下文
                int startIndex = Math.max(0, historyMessages.size() - 10);
                allMessages.addAll(historyMessages.subList(startIndex, historyMessages.size()));
            }
            
            // 添加当前用户消息
            Map<String, Object> currentMessage = new HashMap<>();
            currentMessage.put("role", "user");
            currentMessage.put("content", userMessage);
            currentMessage.put("content_type", "text");
            allMessages.add(currentMessage);
            
            requestBody.put("additional_messages", allMessages);

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + ACCESS_TOKEN);

            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

            // 发送请求
            ResponseEntity<String> response = restTemplate.postForEntity(API_URL, request, String.class);
            
            if (response.getStatusCode() == HttpStatus.OK) {
                return parseNonStreamResponse(response.getBody());
            } else {
                return "抱歉，智能助手暂时无法回复，请稍后再试。";
            }
            
        } catch (Exception e) {
            System.err.println("调用扣子API失败: " + e.getMessage());
            e.printStackTrace();
            return "抱歉，智能助手暂时无法回复，请稍后再试。";
        }
    }

    /**
     * 兼容旧版本的方法
     */
    public String sendMessage(String userMessage, String cozeUserId) {
        return sendMessage(userMessage, cozeUserId, null);
    }

    /**
     * 解析非流式响应
     * @param responseBody 响应体
     * @return 解析后的回复内容
     */
    private String parseNonStreamResponse(String responseBody) {
        try {
            JsonNode jsonNode = objectMapper.readTree(responseBody);
            
            // 检查响应状态
            if (jsonNode.has("code") && jsonNode.get("code").asInt() != 0) {
                String errorMsg = jsonNode.path("msg").asText("API调用失败");
                System.err.println("扣子API错误: " + errorMsg);
                return "抱歉，智能助手暂时无法回复，请稍后再试。";
            }
            
            JsonNode dataNode = jsonNode.path("data");
            
            // 检查对话状态
            String status = dataNode.path("status").asText("");
            String conversationId = dataNode.path("conversation_id").asText("");
            String chatId = dataNode.path("id").asText("");
            
            System.out.println("对话状态: " + status + ", 会话ID: " + conversationId + ", 聊天ID: " + chatId);
            
            if ("in_progress".equals(status)) {
                // 对话还在进行中，需要轮询获取结果
                return pollForResult(conversationId, chatId);
            } else if ("completed".equals(status)) {
                // 对话已完成，获取消息列表
                return getMessagesFromConversation(conversationId, chatId);
            } else if ("failed".equals(status)) {
                System.err.println("对话失败: " + dataNode.path("last_error").path("msg").asText());
                return "抱歉，智能助手处理失败，请重新发送消息。";
            }
            
            // 如果状态未知，尝试直接获取消息
            return getMessagesFromConversation(conversationId, chatId);
            
        } catch (Exception e) {
            System.err.println("解析非流式响应失败: " + e.getMessage());
            e.printStackTrace();
            return "解析回复时出现问题，请重新发送消息。";
        }
    }

    /**
     * 轮询获取对话结果
     * @param conversationId 会话ID
     * @param chatId 聊天ID
     * @return 最终回复内容
     */
    private String pollForResult(String conversationId, String chatId) {
        int maxAttempts = 60; // 最多轮询60次
        int delayMs = 2000; // 每次间隔2秒
        
        for (int attempt = 0; attempt < maxAttempts; attempt++) {
            try {
                Thread.sleep(delayMs);
                
                // 首先检查对话状态
                String retrieveUrl = "https://api.coze.cn/v3/chat/retrieve?conversation_id=" + conversationId + "&chat_id=" + chatId;
                
                // 设置请求头
                HttpHeaders headers = new HttpHeaders();
                headers.set("Authorization", "Bearer " + ACCESS_TOKEN);
                
                HttpEntity<String> request = new HttpEntity<>(headers);
                
                // 发送查询请求
                ResponseEntity<String> response = restTemplate.exchange(retrieveUrl, HttpMethod.GET, request, String.class);
                
                if (response.getStatusCode() == HttpStatus.OK) {
                    JsonNode jsonNode = objectMapper.readTree(response.getBody());
                    JsonNode dataNode = jsonNode.path("data");
                    String status = dataNode.path("status").asText("");
                    
                    System.out.println("轮询第" + (attempt + 1) + "/" + maxAttempts + "次，状态: " + status + 
                                     " (预计最大等待时间: " + (maxAttempts * delayMs / 1000) + "秒)");
                    
                    if ("completed".equals(status)) {
                        // 对话完成，获取消息列表
                        return getMessagesFromConversation(conversationId, chatId);
                    } else if ("failed".equals(status)) {
                        System.err.println("对话失败: " + dataNode.path("last_error").path("msg").asText());
                        return "抱歉，智能助手处理失败，请重新发送消息。";
                    }
                    // 如果还是in_progress，继续轮询
                }
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return "请求被中断，请重新发送消息。";
            } catch (Exception e) {
                System.err.println("轮询失败: " + e.getMessage());
            }
        }
        
        System.out.println("AI处理超时，已轮询" + maxAttempts + "次，总等待时间: " + (maxAttempts * delayMs / 1000) + "秒");
        return "智能助手正在处理复杂问题，响应时间较长。请稍后重新发送消息，或尝试简化问题。";
    }

    /**
     * 从对话中获取消息列表
     * @param conversationId 会话ID
     * @param chatId 聊天ID
     * @return AI回复内容
     */
    private String getMessagesFromConversation(String conversationId, String chatId) {
        try {
            // 构建消息列表查询URL
            String messageListUrl = "https://api.coze.cn/v3/chat/message/list?conversation_id=" + conversationId + "&chat_id=" + chatId;
            
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + ACCESS_TOKEN);
            
            HttpEntity<String> request = new HttpEntity<>(headers);
            
            // 发送请求获取消息列表
            ResponseEntity<String> response = restTemplate.exchange(messageListUrl, HttpMethod.GET, request, String.class);
            
            if (response.getStatusCode() == HttpStatus.OK) {
                JsonNode jsonNode = objectMapper.readTree(response.getBody());
                
                // 检查响应状态
                if (jsonNode.has("code") && jsonNode.get("code").asInt() != 0) {
                    System.err.println("获取消息列表失败: " + jsonNode.path("msg").asText());
                    return "获取AI回复失败，请重新发送消息。";
                }
                
                JsonNode dataArray = jsonNode.path("data");
                if (dataArray.isArray()) {
                    // 遍历消息，找到assistant的回复
                    for (JsonNode messageNode : dataArray) {
                        String role = messageNode.path("role").asText("");
                        String type = messageNode.path("type").asText("");
                        
                        // 查找assistant角色且类型为answer的消息
                        if ("assistant".equals(role) && "answer".equals(type)) {
                            String content = messageNode.path("content").asText("");
                            if (!content.isEmpty()) {
                                System.out.println("获取到AI回复: " + content);
                                return content;
                            }
                        }
                    }
                }
                
                return "AI已处理您的消息，但未生成回复内容。";
            } else {
                System.err.println("获取消息列表失败，状态码: " + response.getStatusCode());
                return "获取AI回复失败，请重新发送消息。";
            }
            
        } catch (Exception e) {
            System.err.println("获取消息列表异常: " + e.getMessage());
            e.printStackTrace();
            return "获取AI回复时出现异常，请重新发送消息。";
        }
    }

    /**
     * 解析流式响应
     * @param responseBody 响应体
     * @return 解析后的回复内容
     */
    private String parseStreamResponse(String responseBody) {
        try {
            // 查找包含最终消息的行
            Pattern pattern = Pattern.compile("event:conversation\\.message\\.completed\\ndata:(.*?)\\n");
            Matcher matcher = pattern.matcher(responseBody);
            
            if (matcher.find()) {
                String jsonData = matcher.group(1);
                JsonNode jsonNode = objectMapper.readTree(jsonData);
                return jsonNode.path("content").asText();
            }
            
            // 如果没找到完整消息，尝试解析其他类型的响应
            String[] lines = responseBody.split("\n");
            for (String line : lines) {
                if (line.startsWith("data:") && !line.equals("data:")) {
                    try {
                        String jsonData = line.substring(5); // 移除"data:"前缀
                        JsonNode jsonNode = objectMapper.readTree(jsonData);
                        
                        if (jsonNode.has("content") && !jsonNode.path("content").asText().isEmpty()) {
                            return jsonNode.path("content").asText();
                        }
                    } catch (Exception e) {
                        // 继续尝试下一行
                        continue;
                    }
                }
            }
            
            return "智能助手收到了您的消息，正在思考中...";
            
        } catch (Exception e) {
            System.err.println("解析响应失败: " + e.getMessage());
            return "解析回复时出现问题，请重新发送消息。";
        }
    }



    /**
     * 生成唯一的用户ID
     * @param username 用户名
     * @return 唯一ID
     */
    public String generateUserId(String username) {
        return "user_" + username + "_" + System.currentTimeMillis();
    }
    

} 